package com.chenfan.mcn.mq.message;

import com.alibaba.fastjson.annotation.JSONType;
import lombok.Data;
import org.apache.commons.lang3.ArrayUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Date;
import java.util.Map;

/**
 * 元消息-多态区分消息类型(typeKey)：{\"messageType\":${typeName}}，替换@type
 *
 * @author wulg
 * @date 2021-08-04
 **/
@Data
@JSONType(typeKey="messageType", seeAlso = { CfChargeCommonMessage.class, CfInvoiceMessage.class, CfTaxInvoiceMessage.class,
        ChargeAutoTaxInvoiceMessage.class, ChargeAutoInvoiceMessage.class})
public abstract class AbstractMetaMessage {

    /**
     * 创建人
     */
    private Long createBy;

    /**
     * 创建人名称
     */
    private String createName;

    /**
     * 创建日期
     */
    private Date createDate;

    /**
     * 部门ID
     */
    private Long departmentId;

    /**
     * 公司
     */
    private Long companyId;

    /**
     * 租户id
     */
    private Long tenantId;

    /**
     * 更新人
     */
    private Long updateBy;

    /**
     * 更新人名称
     */
    private String updateName;

    /**
     * 更新日期
     */
    private Date updateDate;

    /*static {
        MetaMessage.registerSeeAlso(CfChargeCommonMessage.class);
    }*/
    /**
     * 提供MMetaMessage@JsonType->seeAlso扩展-静态执行注册
     * @param classes
     */
    @SafeVarargs
    public static void registerSeeAlso(Class<? extends AbstractMetaMessage>... classes) {
        try {
            if (ArrayUtils.isNotEmpty(classes)) {
                JSONType annotation = AbstractMetaMessage.class.getAnnotation(JSONType.class);
                Class<?>[] seeAlso = annotation.seeAlso();
                for(Class<? extends AbstractMetaMessage> clazz : classes){
                    if(!ArrayUtils.contains(seeAlso,classes)){
                        seeAlso = ArrayUtils.add(seeAlso,clazz);
                    }
                }
                InvocationHandler ih = Proxy.getInvocationHandler(annotation);
                Field memberValuesField = ih.getClass().getDeclaredField("memberValues");
                memberValuesField.setAccessible(true);
                Map memberValues = (Map) memberValuesField.get(ih);
                memberValues.put("seeAlso", seeAlso);
            }
        } catch (Exception e) {
            throw new IllegalStateException("MetaMessage@JsonType -> static resister seeAlso exception",e);
        }
    }

    /*public static void main(String[] args) {
        String msgJson1 = "{\"chargeCode\":\"123123213\",\"chargeId\":123}";
        CfChargeCommonMessage message = new CfChargeCommonMessage();
        message.setChargeId(12321L);
        message.setChargeCode("test");
        String msgJson2 = JSON.toJSONString(message, SerializerFeature.WriteClassName);
        Object object = JSON.parseObject(msgJson2,MetaMessage.class);
        System.out.println(object);
    }*/
}
